package com.htpay.util.sdk;

import com.htpay.util.MD5Util;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
 * 惠通客户端、签名校验等相关的工具类
 */
@Slf4j
public class HTPayClientUtil {
    public static String HTTP_URL = "http://microchat.15zxm.cn:3001/openApi/api/charge?";

    /**
     * bean转map对象
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> Obj2Map(Object obj) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.get(obj) != null) {
                String val = field.get(obj).toString();
                if (val.contains("http://") || val.contains("https://")) {
                    map.put(field.getName(), URLEncoder.encode(val, "utf-8"));
                } else
                    map.put(field.getName(), val);
            }
        }
        return map;
    }

    /**
     * 发送工具类
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        String result = "";
        try {
            URL getUrl = new URL(url);
            HttpURLConnection urlConnection = (HttpURLConnection) getUrl.openConnection();
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            urlConnection.getInputStream()));

            result = in.readLine().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info(result);
        return result;
    }

    /**
     * 参数序列化, e.g: a=1&b=2...
     *
     * @param parameters
     * @return
     */
    public static String serializeUrlParams(Map<String, Object> parameters) {
        StringBuffer params = new StringBuffer();
        List<String> keyList = new ArrayList<>(parameters.keySet());
        for (int i = 0; i < keyList.size(); i++) {
            String k = keyList.get(i);
            Object v = parameters.get(k);
            //空值不传递，不参与签名组串
            if (null != v && !"".equals(v)) {
                params.append(k + "=" + v + "&");
            }
        }
        String p = params.toString();
        if (p.length() > 1)
            return p.substring(0, p.length() - 1);
        else return "";
    }

    /**
     * 根据私密钥匙加密
     *
     * @param parameters
     * @param merchantKey
     * @return
     * @throws Exception
     */
    public static String createSign(Map<String, Object> parameters, String merchantKey) {
        log.info(parameters.keySet().toString());
        StringBuffer sbKey = new StringBuffer();
        List<String> keyList = new ArrayList<>(parameters.keySet());
        // 所有参与传参的参数按照accsii排序（升序）
        Collections.sort(keyList);
        for (int i = 0; i < keyList.size(); i++) {
            String k = keyList.get(i);
            Object v = parameters.get(k);
            //空值不传递，不参与签名组串
            if (null != v && !"".equals(v)) {
                sbKey.append(k + "=" + v + "&");
            }
        }
        sbKey.append("key=" + merchantKey);
        log.info("==== 携带私钥字符串:" + sbKey.toString() + " ====");
//        System.out.println();
        //MD5加密,结果转换为大写字符
        String sign = MD5Util.MD5Encode(sbKey.toString(), "utf-8").toUpperCase();
        log.info("==== 根据接口访问数据获取sign[" + sign + "] ====");
        return sign;
    }

    public static void main(String[] args) throws Exception {
        //创建订单交易参数
        HTPayClientParams params = new HTPayClientParams("1000", "101", "http://test.example.com", "HT20191225153950123456", "100.0");

        //生成商户秘钥
        Map<String, Object> parameters = HTPayClientUtil.Obj2Map(params);
        String sign = createSign(parameters, "商户skey");
        parameters.put("sign", sign);

        String url = HTPayClientUtil.HTTP_URL + HTPayClientUtil.serializeUrlParams(parameters);
        System.out.println(url);

        //调用充值接口
        HTPayClientUtil.get(url);
    }
}
